package kgc.crm.aop;
import kgc.crm.annotation.UserPower;
import kgc.crm.util.*;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

@Slf4j
@Component
@Aspect //作⽤是把当前类标识为⼀个切⾯供容器读取
public class UserPowerAop {
    @Autowired
    private RedisBean redisBean;
//Pointcut 切点，指被方法上打上这个主角的都会被增强，增强的内容的就是权限验证
    @Pointcut("@annotation(kgc.crm.annotation.UserPower)")
    public void UserPower() {
    }

    //JoinPoint切入点
    @Around("UserPower()") //通知 before 等等都是通知，方法进入前所做的增强的通知
    public Object verrifcation(ProceedingJoinPoint joinPoint) {
        //验证token 的完整性
        //在aop容器中获取request对象
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = (HttpServletRequest) requestAttributes.
                resolveReference(RequestAttributes.REFERENCE_REQUEST);

        Long id = JWTManager.getUserIDByToken(RequestUtil.getApiToken(request));
        String menuId = request.getHeader(Constant.MENU_NAME);
        Signature signature = joinPoint.getSignature();
        String name = signature.getName();
        Object target = joinPoint.getTarget();
        Class<?> aClass = target.getClass();
        String realm = "";
        try {
            Method[] methods = aClass.getMethods();
            for (Method method : methods) {
                if (!method.getName().equals(name))
                    continue;
                    UserPower power = method.getAnnotation(UserPower.class);
                    realm = power.power().getDesc();
                    break;
            }
        } catch (Exception e) {
            log.error("权限验证不通过:{}",e);
            return new ResponseEntity(new CommonResult(500,"erroe","该用户没有权限"), HttpStatus.INTERNAL_SERVER_ERROR);
        }

        if (EmptyChecker.isEmpty(realm)) {
            log.error("权限验证不通过，realm 获取为空");
            return new ResponseEntity(new CommonResult(500,"erroe","权限获取为空"), HttpStatus.INTERNAL_SERVER_ERROR);
        }

        String key = id +Constant.PINGJIE+ menuId +Constant.PINGJIE+realm;
        if (!redisBean.hasKey(key)){
           log.error("权限验证不通过，该用户没有权限");
           return new ResponseEntity(new CommonResult(500,"erroe","无权限"), HttpStatus.INTERNAL_SERVER_ERROR);
       }

        Object proceed = null;
        try {
            //如果通过验证，则直接调用请求方法
            proceed = joinPoint.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return proceed;
    }
}